<?php


namespace App\Models\CacheModel\live;


use App\Models\Api\BaseCache;
use think\Cache;
use think\Log;
use AstroTool\Cache\CacheManage;

class LiveUserContribution extends BaseCache
{
    protected $table = 'wechat_backup_07_18_14_43_00.live_user_contribution';

    protected $cacheModel = 'live.user_contribution';

    /**
     * 获取贡献值排行榜信息
     * @param int $liveId
     * @param int $page
     * @param int $limit
     * @return array
     * @throws \Exception
     */
    public function getContributionRanking(int $liveId, int $page = 1, int $limit = 10): array
    {
        $rankingData = CacheManage::getInstance()
            ->setCacheConfig($this->cacheModel, $liveId)
            ->setPage($page)
            ->setPageSize($limit)
            ->setSort('desc')
            ->getListPageDataIds(function ($ids = [], $isCache = true, $sortType = 'desc') use ($liveId)
            {
                try
                {
                    $data = $this->where('live_id', $liveId)
                        ->order("contribution_value {$sortType},update_time {$sortType}")
                        ->limit(50)
                        ->column('contribution_value,create_time,update_time', 'uid');

                    $resData = [];
                    foreach ($data as $uid => $dataItem)

                    {
                        $a = $dataItem['update_time'] - 1600000000;
                        $s = ((1000000000 - $a) / 1000000000);
                        $resData[$uid] = ['contribution_value' => $dataItem['contribution_value'] + $s];
                    }

                    return $resData;
                }
                catch (\Exception $e)
                {
                    return [];
                }
            }, 'contribution_value', 0);

        $resData = [];
        $ranking = ($page - 1) * 10 + 1;
        if (is_array($rankingData['data']))
        {
            foreach ($rankingData['data'] as $uid => $contributionValueScore)
            {
                $resData[$uid] = [
                    'uid' => $uid,
                    'ranking' => $ranking,
                    'contribution_value' => (int)($contributionValueScore)
                ];

                $ranking++;
            }
        }

        $rankingData['data'] = $resData;

        return $rankingData;
    }

    /**
     * 获取用户直播间 排名信息
     * @param int $liveId
     * @param int $uid
     * @param int $rankingRange 获取排名范围 最大50 最小1     例如想获取是否为前3名 则 $rankingRange = 3
     * @return int|mixed
     * @throws \Exception
     */
    public function getUserRanking(int $liveId, int $uid, int $rankingRange = 50)
    {
        $rankingData = $this->getContributionRanking($liveId, 1, $rankingRange);

        if (isset($rankingData['data'][$uid]))
        {
            return $rankingData['data'][$uid]['ranking'];
        } else
        {
            return -1; // $rankingRange 名以外 未上榜
        }
    }

    /**
     * 直播间用户贡献值增加
     * @param int $liveId
     * @param $liveRecordId
     * @param int $uid
     * @param int $inc
     * @return int  // -1 服务异常 0=>贡献值操作未处理 1=>操作成功 2=>操作成功并且用户荣升傍一
     */
    public function setLiveUserContributionValueInc(int $liveId, $liveRecordId, int $uid, int $inc): int
    {
        if ($inc > 0)
        {
            try
            {
                // 获取用户贡献值信息
                $cacheKeyId = $liveId . ':' . $uid;
                $userContributionInfo = $this->getInfoById($cacheKeyId, ['id', 'contribution_value', 'update_time']);
                // 获取排行榜信息
                $liveConRankList = $this->getContributionRanking($liveId, 1, 50);
                $time = time();
                $day = date('Ymd');
                $oldDayContributionValue = Cache::get('live:user_contribution_value_day:' . $day . '_' . $uid, 0);  // 获取用户当日礼物贡献
                $newDayContributionValue = $oldDayContributionValue + $inc;
                if ($oldDayContributionValue < 500 && $newDayContributionValue >= 500)
                {  // 当日礼物贡献值 超过500
                    (new LiveUserGiftBag())->sendUserGift($uid, 3, 1);// 发放奖品
                    // 添加变动记录
                    $record = [
                        'uid' => $uid,
                        'gid' => 3,
                        'flag' => 2,
                        'flag_type' => 7,
                        'live_record_id' => $liveRecordId,
                        'live_id' => $liveId,
                        'change_num' => 1,
                        'create_time' => $time,
                    ];
                    (new LiveUserGiftBagRecord())->saveData($uid, $record);
                }
                Cache::set('live:user_contribution_value_day:' . $day . '_' . $uid, $newDayContributionValue, 86400);   // 更新用户当日礼物贡献值
                if ($userContributionInfo)
                {
                    $resContributionValue = $userContributionInfo['contribution_value'] + $inc;
                    $updateData = [
                        'contribution_value' => $resContributionValue,
                        'update_time' => $time
                    ];
                    // 更新数据库
                    $this->where('id', (int)$userContributionInfo['id'])->update($updateData);
                    // 更新缓存
                    CacheManage::getInstance()
                        ->setCacheConfig($this->cacheModel, $cacheKeyId)
                        ->setCache($updateData, 'details', true);
                } else
                {   // 没有贡献值    初始化数据
                    $resContributionValue = $inc;
                    $init = [
                        'uid' => $uid,
                        'live_id' => $liveId,
                        'contribution_value' => $resContributionValue,
                        'create_time' => $time,
                        'update_time' => $time
                    ];

                    $this->save($init); // 写入贡献值
                }

                $oldContributionValue = $userContributionInfo['contribution_value'] ?? 0;
                if ($oldContributionValue < 10000 && $resContributionValue >= 10000)
                {   // 累计打到10000贡献值 赠送2个准了暴富
                    (new LiveUserGiftBag())->sendUserGift($uid, 3, 2);// 发放奖品
                    // 添加变动记录
                    $record = [
                        'uid' => $uid,
                        'gid' => 3,
                        'flag' => 2,
                        'flag_type' => 8,
                        'live_record_id' => $liveRecordId,
                        'live_id' => $liveId,
                        'change_num' => 2,
                        'create_time' => $time,
                    ];
                    (new LiveUserGiftBagRecord())->saveData($uid, $record);
                }

                // 判断用户是否上榜 若以前未上榜 则需上榜
                if (isset($liveConRankList['data'][$uid]) || count($liveConRankList['data']) < 50)
                {   //  用户已上榜  更新排行榜上贡献值 || 榜单上用户不足50名用户 直接上榜
                    $score = $resContributionValue + ((1000000000 - ($time - 1600000000)) / 1000000000);
                    $this->listDataAdd($liveId, [$uid => $score]);
                } else
                {
                    $lastInfo = array_pop($liveConRankList['data']);
                    // 榜单上用户达到50名
                    if ($resContributionValue > $lastInfo['contribution_value'])
                    {   // 贡献值超过最后一名 上榜
                        $score = $resContributionValue + ((1000000000 - ($time - 1600000000)) / 1000000000);
                        $this->listDataAdd($liveId, [$uid => $score]);
                    }
                }

                // 判断用户是否晋升榜一
                $firstInfo = current($liveConRankList['data']);
                if ($resContributionValue > $firstInfo['contribution_value'] && $uid != $firstInfo['uid'])
                {   // 贡献值超过了第一名
                    return 2;
                }

                return 1;
            }
            catch (\Exception $e)
            {
                Log::write("直播间用户贡献值新增失败;直播间ID：{$liveId},UID:{$uid},Inc:{$inc};错误消息：{$e->getMessage()};File:{$e->getFile()};Line:{$e->getLine()}", 'error', true);
                return -1;
            }
        }

        return 0;
    }

    /**
     * 重写数据时获取数据
     * @param $ids
     * @param $type
     * @param $sortType
     * @return array
     */
    public function getInfoByIdsInData($ids, $type, $sortType)
    {
        try
        {
            $data = [];
            foreach ($ids as $idItem)
            {
                // ID = 直播间ID:UID
                [$liveId, $uid] = explode(':', $idItem);

                $d = $this->where('live_id', $liveId)->where('uid', $uid)->column('id,live_id,uid,contribution_value,create_time,update_time', 'uid');

                if ($d)
                {
                    $data[$idItem] = $d[$uid];
                }
                // else
                // {   // 没有数据 初始化数据
                //     $time = time();
                //     $init = [
                //         'uid' => $uid,
                //         'live_id' => $liveId,
                //         'contribution_value' => 0,
                //         'create_time' => $time,
                //         'update_time' => $time
                //     ];
                //
                //     $id = $this->insertGetId($init);
                //
                //     $init['id'] = $id;
                //
                //     $data[$idItem] = $init;
                // }
            }
        }
        catch (\Exception $e)
        {
            return [];
        }

        return $data;
    }
}
